home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / The World of Computer Software.iso / mvssrc.zip / GOPHER < prev    next >
Text File  |  1992-04-13  |  6KB  |  188 lines

  1. /*******************************************************************
  2. *
  3. *  This member contains a simple TCP/IP server.  It waits for
  4. *  a tcpip connection request, and then starts a subtask to
  5. *  service that request.
  6. *
  7. *  This server follows the GOPHER protocols defined by UMN.
  8. *  For more information, see the ANONYMOUS FTP site at
  9. *  BOOMBOX.MICRO.UMN.EDU.
  10. *
  11. *******************************************************************/
  12. #pragma nomargins
  13. #include "tcpincl"              /* All system file includes needed. */
  14.  
  15.  
  16. static int     sockfd;              /*socket for accepting connections*/
  17. static struct sockaddr_in server;   /*server address information */
  18.  
  19. #include "ebdasc"               /* ebcdic-->ascii conversion stuff   */
  20. #include "mtferror"             /* MTF error reporting routines      */
  21.  
  22. int tcpsetup(int port,int qlen)
  23. /***************************************************************/
  24. /*
  25. *        This routine sets up the socket connection.
  26. *
  27. *          INPUT:  port  - socket to connect to
  28. *                  qlen  - length of pending request queue len
  29. *
  30. *          OUTPUT: TRUE  - successfully set up socket
  31. *                  FALSE - socket setup failed.
  32. */
  33. /***************************************************************/
  34. {
  35. int x;       /* loop counter*/
  36. struct linger l;                    /* linger for setsockopt */
  37.  
  38. /*    initialize the MTF  environment.                   */
  39.  
  40. if(mtfichk(tinit("GPHPTSK", MTF_TASKS))!=0) exit(8);
  41. /*       open a TCP socket...                            */
  42.  
  43. if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
  44.     {
  45.     tcperror("SOCKET - ");
  46.     return(0);
  47.     };
  48.  
  49. /*  set the linger option on so we wait for data to be sent... */
  50. l.l_onoff = 1;
  51. l.l_linger=100;           /* wait 100 seconds before giving up */
  52. if(setsockopt(sockfd,SOL_SOCKET,SO_LINGER,(char *) &l,sizeof(l))<0)
  53.     {
  54.     tcperror("SETSOCKOPT - ");
  55.     }
  56.  
  57. /*    now bind our local address so that the client can send to us */
  58.  
  59. bzero((char *) &server, sizeof(server));
  60. server.sin_family           =   AF_INET;
  61. server.sin_addr.s_addr      =   INADDR_ANY;
  62. server.sin_port             =   htons(port);
  63. if (bind(sockfd, &server, sizeof(server))<0)
  64.     {
  65.     tcperror("BIND - ");
  66.     return(0);
  67.     }
  68.  
  69. /*    now set length of the connection queue... */
  70. if (listen(sockfd,qlen)!=0)
  71.     {
  72.     tcperror("LISTEN -");
  73.     }
  74. return(1);
  75. }
  76. void spawn(int newsockfd)
  77. /********************************************************************/
  78. /*
  79. *       This routine starts a subtask, passing control of a socket
  80. *       to it.  It then waits for the subtask to take the socket and
  81. *       then closes the socket.
  82. *
  83. *       INPUT: newsockfd - socket descriptor to give to subtask.
  84. */
  85. /********************************************************************/
  86. {
  87. struct clientid clid;
  88. char mysname[8];
  89.  
  90.      if(getclientid(AF_INET,&clid)<0) tcperror("GETCLIENTID");
  91.      clid.domain = AF_INET;
  92.      memcpy(mysname,clid.subtaskname,8);
  93.      memcpy(clid.subtaskname,"        ",8);
  94.      if(givesocket(newsockfd,&clid) != 0) tcperror("GIVESOCKET");
  95.      memcpy(clid.subtaskname,mysname,8);
  96.      if(mtfscchk(tsched(MTF_ANY,"receive",newsockfd,clid))!=0) exit(4);
  97.      if (closesock(newsockfd)<0) printf("Connection timed out!");
  98. }
  99. int closesock(int newsockfd)
  100. /********************************************************************/
  101. /*
  102. *   This routine waits for an exception on the socket.  When one
  103. *   occurs (by a subtask's "TAKESOCKET"!) we'll close our (the main
  104. *   task's) connection to it.
  105. *
  106. *               INPUT   s   pointer to socket descripter.
  107. *               OUTPUT  rc  -1 = connection timed out...
  108. *                            0 = an excption occured!
  109. */
  110. /********************************************************************/
  111. {
  112.      int temps;
  113.      struct sockaddr clientaddress;
  114.      int addrlen;
  115.      int maxfdpl;
  116.      struct fd_set readmask;
  117.      struct fd_set writmask;
  118.      struct fd_set exepmask;
  119.      int rc;
  120.      struct timeval time;
  121.  
  122.      temps = newsockfd;
  123.      time.tv_sec = CONNECT_TIME_OUT;
  124.      time.tv_usec = 0;
  125.      maxfdpl = temps + 1;
  126.  
  127.      FD_ZERO(&readmask);
  128.      FD_ZERO(&writmask);
  129.      FD_ZERO(&exepmask);
  130.      FD_SET(temps, &exepmask);
  131.  
  132.      rc = select(maxfdpl, &readmask, &writmask, &exepmask, &time);
  133.  
  134.      if (rc < 0)
  135.           {
  136.           tcperror("SELECT - ");
  137.           return rc;
  138.           }
  139.      else
  140.           {
  141.           if(rc=0) printf("The GIVESOCKET timed out!\n");
  142.           if(close(newsockfd)<0) tcperror("CLOSE -");
  143.           return rc;
  144.           }
  145. }
  146. int main(void)
  147. {
  148. int x;                             /* loop counter*/
  149. char buffer[255];                  /* buffer for input/output*/
  150. int newsockfd;                     /*new connection socket...*/
  151. struct sockaddr_in client;         /*client address information */
  152. struct clientid clid;              /*client info for givesocket */
  153. int clientlen;                     /*new connection socket...*/
  154.  
  155. /******************************************************************/
  156. /*         set up the connection to the socket...                 */
  157. /******************************************************************/
  158. if(!tcpsetup(SERV_TCP_PORT,TCP_QUEUE_LENGTH))
  159.     {
  160.     printf("could not set up the tcpip environment!\n");
  161.     exit(16);
  162.     }
  163. /******************************************************************/
  164. /*         Now loop, waiting for a connection request.            */
  165. /******************************************************************/
  166.  
  167.     clientlen = sizeof(client);
  168.     x = 0;
  169.     while(1==1)
  170.     {
  171.     if((newsockfd=accept(sockfd,&client,&clientlen)) == -1)
  172.         {
  173.         tcperror("ACCEPT - ");
  174.         exit(8);
  175.         }
  176.     x++; 
  177.     spawn(newsockfd);
  178.     };
  179. /******************************************************************/
  180. /*         Wait for all pending tasks to complete (should never   */
  181. /*         run, since I haven't added PURGE support yet...)       */
  182. /*         then shut down subtasks.                               */
  183. /******************************************************************/
  184. if(tsyncro(MTF_ALL)!=0) perror("TSYNCRO");
  185. if(mtfsychk(tsyncro(MTF_ALL))!=0) exit(8);
  186. if(mtftrchk(tterm())!=4) exit(8);
  187. }
  188.